const Client = require('../../Mongoose/OauthClient')
const Token = require('../../Mongoose/OauthAccessToken')
const Code = require('../../Mongoose/OauthCode')
const User = require('../../Mongoose/User')
const Jwt = require('../../Lib/Jwt')
class OauthController {
    constructor() {

    }
    async authorize(ctx, next) {
        if (ctx.method == 'GET') {
            let redirect_uri = ctx.query.redirect_uri
            let client_id = ctx.query.client_id
            let client = await Client.findOne({ _id: client_id })
            if (!client) {
                ctx.throw('客户端不存在')
            }
            if (redirect_uri != client.redirect_uri) {
                ctx.throw('跳转地址不正确')
            }
            await ctx.render('oauth/authorize/index', { client: client })
        } else {
            let state = ctx.request.body.state
            let client_id = ctx.request.body.client_id
            let client = await Client.findOne({ _id: client_id })

            // 同意授权
            if (state) {
                let data = {
                    user_id: ctx.state.user_id,
                    client_id: client.id,
                    invoked: 0,
                    expires_at: Date.now() + 60 * 10 * 1000 // code有效期10分钟
                }
                let code = await Code.create(data)
                await ctx.redirect(`${client.redirect_uri}?code=${code.id}`)
            } else {
                let msg = '用户取消授权'
                let err = '500001'
                await ctx.redirect(`${client.redirect_uri}?err=${err}&msg=${msg}`)
            }

        }
    }
    /**
     * token
     * 
     * @param {any} ctx 
     * @param {any} next 
     * @memberof OauthController
     */
    async token(ctx, next) {
        let grant_type = ctx.request.body.grant_type //生成token的类型  authorization_code password refresh_token
        if (grant_type == 'authorization_code') {
            let data = {
                client_id: ctx.request.body.client_id,
                client_secret: ctx.request.body.client_secret,
                redirect_uri: ctx.request.body.redirect_uri,
                code: ctx.request.body.code
            }
            // 校验code
            let code = await Code.findById(data.code)
            if (!code) {
                ctx.throw('code 不合法')
            }
            let client = await Client.findById(data.client_id)
            if (!client) {
                ctx.throw('客户端验证错误')
            }
            //code 与client 匹配
            if (code.client_id != client.id) {
                ctx.throw('code 不匹配')
            }
            // 验证回调
            if (client.redirect_uri != data.redirect_uri) {
                ctx.throw('回调地址不匹配')
            }
            // access-token加密数据
            let user = await User.findById(client.user_id)
            let sign_data = {
                user_id: user.id,
                client_id: client.id,
                client_name: client.name,
                username: user.username,
                display_name: user.display_name
            }
            // 生成token
            let token = {
                user_id: user.id,
                client_id: client.id,
                access_token: await Jwt.sign(sign_data),
                name: client.name,
                scopes: client.scopes,
                revoked: 0,
                expires_at: Date.now() + 1000 * 86400 * 1,
            }
            let res = await Token.create(token)
            ctx.body = res
        } else if (grant_type == 'password') {
            let data = {
                client_id: ctx.request.body.client_id,
                client_secret: ctx.request.body.client_secret,
                username: ctx.request.body.username,
                password: ctx.request.body.password,
                scope: ctx.request.body.scope,
            }

            let user = await User.check_password(data.username, data.password)
            if (!user) {
                ctx.throw('用户名或密码错误')
            }
            let client = await Client.findById(data.client_id)
            if (!client) {
                ctx.throw('客户端不存在')
            }
            if (client.secret != data.client_secret) {
                ctx.throw('秘钥错误')
            }
            // access-token加密数据
            let sign_data = {
                user_id: user.id,
                client_id: client.id,
                client_name: client.name,
                username: user.username,
                display_name: user.display_name
            }
            // 生成token
            let token = {
                user_id: user.id,
                client_id: client.id,
                access_token: await Jwt.sign(sign_data),
                name: client.name,
                scopes: client.scopes,
                revoked: 0,
                expires_at: Date.now() + 1000 * 86400 * 1,
            }
            let res = await Token.create(token)
            ctx.body = res            
        } else if (grant_type == 'refresh_token') {
            data = {
                client_id: ctx.request.body.client - id,
                client_secret: ctx.request.body.client_secret,
                refresh_token: ctx.request.body.refresh_token,
                scope: ctx.request.body.scope,
            }
            ctx.body = data            
        }
    }
}
module.exports = new OauthController()